using System;
using System.Collections.Generic;
using System.Text;
using PicoInterface;

namespace RapidHDL
{
    public class TestFIFOInterface : RapidHardware
    {
    
        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.ForceBuildHardware = false;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 10;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = false;
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            // why required?
            //Utility.SinkExtraBits(TopLevelComponent, TopLevelComponent.MainReset);
            Utility.SourceExtraBits(TopLevelComponent, TopLevelComponent.TestBusWrite, 0);

            //Utility.SinkExtraBits(TopLevelComponent, TopLevelComponent.FIFOInterface.InputFIFOData);
            //Utility.SinkExtraBits(TopLevelComponent, TopLevelComponent.FIFOInterface.InputStatusReg);
            //Utility.SinkExtraBits(TopLevelComponent, TopLevelComponent.TestBusRead);

            //SystemInterface.AddSignalSource("fifo_out", TopLevelComponent.FIFOInterface.OutputFIFOData, 0);
            //SystemInterface.AddSignalSource("fifo_write", TopLevelComponent.FIFOInterface.OutputFIFOWrite, 0);
            //SystemInterface.AddSignalSource("fifo_read", TopLevelComponent.FIFOInterface.OutputFIFORead, 0);

            //SystemInterface.AddSignalSource("pipe_data_out", TopLevelComponent.FIFOInterface.BusFromInternal.Data, 0);
            //SystemInterface.AddSignalSource("pipe_data_out_ready", TopLevelComponent.FIFOInterface.BusFromInternal.DataReady, 0);
            //SystemInterface.AddSignalSource("pipe_data_in_stall", TopLevelComponent.FIFOInterface.BusFromExternal.Stall, 0);

            PipelineStage oPipeSync = new PipelineStage(TopLevelComponent, "pipe_sync", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 16);

            oPipeSync.OutputBus.Join(TopLevelComponent.FIFOInterface.BusFromInternal);

            PipelineReMap oPipeMap = new PipelineReMap(TopLevelComponent.FIFOInterface.BusFromExternal, oPipeSync.InputBus);
            oPipeMap.DefineMap(0, 16, 0,true);
            oPipeMap.CompleteMap();

            Utility.SinkExtraBits(TopLevelComponent,TopLevelComponent.FIFOInterface.BusFromInternal.Data);

            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            SystemInterface.AddSignalView("fifo_status", "fifo_ifc.i_status_reg");
            SystemInterface.AddSignalView("fifo_in", "fifo_ifc.i_fifo_data");
            
            /*SystemInterface.AddSignalView("fifo_in", TopLevelComponent.FIFOInterface.InputFIFOData,0,14,true);
            SystemInterface.AddSignalView("fifo_seq", TopLevelComponent.FIFOInterface.InputFIFOData, 16, 17,true);
            SystemInterface.AddSignalView("fifo_status", TopLevelComponent.FIFOInterface.InputStatusReg);
            SystemInterface.AddSignalView("test", TopLevelComponent.FIFOInterface.Test);
            */

            SystemInterface.AddSignalView("pipe_data_in", TopLevelComponent.FIFOInterface.BusFromExternal.Data);
            SystemInterface.AddSignalView("pipe_data_in_ready", TopLevelComponent.FIFOInterface.BusFromExternal.DataReady);
            SystemInterface.AddSignalView("pipe_data_out_stall", TopLevelComponent.FIFOInterface.BusFromInternal.Stall);

            SystemInterface.AddSignalView("pipe_data_out", TopLevelComponent.FIFOInterface.BusFromInternal.Data);
            SystemInterface.AddSignalView("pipe_data_out_ready", TopLevelComponent.FIFOInterface.BusFromInternal.DataReady);
            SystemInterface.AddSignalView("pipe_data_in_stall", TopLevelComponent.FIFOInterface.BusFromExternal.Stall);


            return true;
        }

        public override bool GenerateHardwareScripts()
        {
            HardwareScript oScript = HardwareScripts.NewScript("test");
            /*oScript.NoReset = true;
            oScript.SignalOut(2, "fifo_read","1");
            oScript.SignalOut(17, "fifo_read", "0");
            for (int idx = 1; idx < 16; idx++)
            {
                oScript.SignalView(idx, "fifo_in", SignalFormat.Unsigned);
                oScript.SignalView(idx, "test", SignalFormat.Unsigned);
                oScript.SignalView(idx, "fifo_seq",SignalFormat.Binary);
            }*/

            /*HardwareScript oScript = HardwareScripts.NewScript("test");
            oScript.SignalOut(1, "fifo_out", "2", SignalFormat.Unsigned);
            oScript.SignalOut(1, "fifo_write", "1");
            oScript.SignalOut(2, "fifo_out", "3", SignalFormat.Unsigned);
            oScript.SignalOut(2, "fifo_write", "1");
            oScript.Pause(3);
            oScript.SignalOut(3, "fifo_out", "4", SignalFormat.Unsigned);
            oScript.SignalOut(3, "fifo_write", "1");
            // 4 also writes a 4
            oScript.SignalOut(5, "fifo_write", "0");
            oScript.Pause(6);
            oScript.SignalOut(6, "fifo_out", "6", SignalFormat.Unsigned);
            oScript.SignalOut(6, "fifo_write", "1");
            oScript.Pause(7);
            oScript.SignalOut(7, "fifo_out", "7", SignalFormat.Unsigned);
            oScript.SignalOut(7, "fifo_write", "1");
            oScript.Pause(8);
            oScript.SignalOut(8, "fifo_write", "0");*/
            


            return true;
        }

        const int len = 4;

        public static void PCTestRead()
        {
            ushort[] data = new ushort[len*2];
            PicoIO.ReadArray(data, len*2);
            string sResult = "";
            for (int x = 0; x < len*2; x++)
            {
                sResult += data[x].ToString() + "\n";
            }
            System.Windows.Forms.MessageBox.Show(sResult);
        }

        public static void PCTestPost()
        {
            ushort[] data = new ushort[len];
            for (int x = 0; x < len; x++)
            {
                data[x] = (ushort)(x * 2 + 1);
            }

            PicoIO.WriteArray(data, len);
        }

        public static void PCTest()
        {
            PCTestPost();
            System.Threading.Thread.Sleep(100);
            PCTestRead();
            PCTestPost();
        }
    }
}


